import cn.org.donald.framework.constant.TableConstant;
import cn.org.donald.framework.util.FileUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;

/**
 * 创建代码专用模块
 * @author Donald
 * @since 2020-12-27 00:48:13
 */
public class BuildCodeApplication {
    private static final String[] PUBLIC_COLUMN = new String[]{"id","created_by","modified_by","creator","modifier","gmt_created","gmt_modified","deleted","version"};

    private static final String SUPER_ENTITY_CLASS = "cn.org.donald.framework.base.BaseEntity";

    private static final String SUPER_CONTROLLER_CLASS = "cn.org.donald.framework.base.BaseController";
    public static void main(String[] args) {
        String author = "Donald";
        String[] tables = {"deploy_command","deploy_log","deploy_project"};
        String dataSourceUrl = "jdbc:mysql://127.0.0.1:3306/donald_deploy?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        String dataSourceUsername = "root";
        String dataSourcePassword = "123456";
        String dataSourceDriverClassName = "com.mysql.cj.jdbc.Driver";

        String projectPath = System.getProperty("user.dir");/*获取项目路径*/


        //需要先构建一个代码自动生成对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //配置策略

        //1.全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        System.out.println(projectPath);
        globalConfig.setOutputDir(projectPath+"/donald-build-code/src/main/java");/*代码生成就到这个目录下了*/
        globalConfig.setAuthor(author);/*生成作者名字*/
        globalConfig.setOpen(false);//是否打开资源管理器
        globalConfig.setFileOverride(false);/*是否覆盖原来的文件*/
        globalConfig.setServiceName("%sService");/*去service的I前缀*/
        globalConfig.setIdType(IdType.AUTO);/*使用自增id*/
        globalConfig.setDateType(DateType.ONLY_DATE);/*配置时间类型*/
        globalConfig.setSwagger2(true);/*是否配置Swagger2*/
        /*将全局配置赋值给自动生成模板*/
        autoGenerator.setGlobalConfig(globalConfig);/*将配置附给自动生成器*/

        //2.配置数据源
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl(dataSourceUrl);/*数据库访问路径*/
        dataSourceConfig.setUsername(dataSourceUsername);/*数据库连接用户名*/
        dataSourceConfig.setPassword(dataSourcePassword);/*数据库连接密码*/
        dataSourceConfig.setDriverName(dataSourceDriverClassName);/*数据库驱动名*/
        dataSourceConfig.setDbType(DbType.MYSQL);/*数据库类型 (MySQL)*/
        /*将数据源配置赋值给自动生成模板*/
        autoGenerator.setDataSource(dataSourceConfig);

        //3.包的配置
        PackageConfig packageConfig = new PackageConfig();
        //packageConfig.setModuleName("system");/*模块名称*/
        packageConfig.setParent("cn.org.donald");/*设置包的上级路径*/
        packageConfig.setEntity("pojo.entity");/*设置实体类的包名*/
        packageConfig.setMapper("mapper");/*设置mapper接口的包名*/
        packageConfig.setService("service");/*设置service的包名*/
        packageConfig.setServiceImpl("service.impl");/*设置service实现类的包名*/
        packageConfig.setController("controller");/*设置controller的包名*/
        /*将包的配置赋值给自动生成器模板*/
        autoGenerator.setPackageInfo(packageConfig);

        //4.策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setSuperEntityClass(SUPER_ENTITY_CLASS);/*父类实体*/
        strategyConfig.setSuperControllerClass(SUPER_CONTROLLER_CLASS);/*父类controller*/
        strategyConfig.setSuperEntityColumns(PUBLIC_COLUMN);
        strategyConfig.setInclude(tables);/*设置要映射的表名,多个表用逗号分隔*/
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);/*数据库命名规则：下划线转驼峰命名*/
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);/*列的命名：下划线转驼峰命名*/
        strategyConfig.setEntityLombokModel(false);/*是否给实体类设置Lombok插件*/
        strategyConfig.setLogicDeleteFieldName(TableConstant.COLUMN_DELETED);/*设置逻辑删除的字段和规则*/

        //4.1.自动填充策略
        ArrayList<TableFill> tableFillList = new ArrayList<>();
        TableFill gmtCreated = new TableFill(TableConstant.COLUMN_GMT_CREATED, FieldFill.INSERT);/*插入时自动填充*/
        TableFill createdBy = new TableFill(TableConstant.COLUMN_CREATE_BY, FieldFill.INSERT);/*插入时自动填充*/
        TableFill gmtModified = new TableFill(TableConstant.COLUMN_GMT_MODIFIED, FieldFill.INSERT_UPDATE);/*更新时自动填充*/
        TableFill modifiedBy = new TableFill(TableConstant.COLUMN_MODIFIED_BY, FieldFill.INSERT_UPDATE);/*更新时自动填充*/
        tableFillList.add(gmtCreated);
        tableFillList.add(createdBy);
        tableFillList.add(gmtModified);
        tableFillList.add(modifiedBy);
        strategyConfig.setTableFillList(tableFillList);/*设置自动填充规则列表*/

        strategyConfig.setVersionFieldName(TableConstant.COLUMN_VERSION);/*设置乐观锁版本号字段*/
        strategyConfig.setRestControllerStyle(true);/*开启controller的rest风格*/
        strategyConfig.setControllerMappingHyphenStyle(true);/*下划线命名*/
        /*将策略赋值给自动生成器模板*/
        autoGenerator.setStrategy(strategyConfig);
        System.out.println(">>>>>>>>>>>正在创建代码文件<<<<<<<<<<<<");
        autoGenerator.execute();
        try {
            System.out.println(">>>>>>>>>>>正在移动文件到指定目录<<<<<<<<<<<<");
            moveFile();
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(">>>>>>>>>>>代码构建成功<<<<<<<<<<<<");
    }

    private static void moveFile() {
        /*移动文件到/resources/mapper/文件夹下*/
        String projectPath = System.getProperty("user.dir");
        String sourcePath = projectPath +
                FileUtil.separator + "donald-build-code"+
                FileUtil.separator +"src"+
                FileUtil.separator+"main"+
                FileUtil.separator+"java"+
                FileUtil.separator+"cn"+
                FileUtil.separator+"org"+
                FileUtil.separator+"donald"
                + FileUtil.separator+"mapper"+
                FileUtil.separator+"xml";

        String targetPath = projectPath+
                FileUtil.separator + "donald-build-code"+
                FileUtil.separator +"src"+
                FileUtil.separator+"main"+
                FileUtil.separator+"resources"+
                FileUtil.separator+"mapper";
        File sourceFile = new File(sourcePath);
        String[] fileList = sourceFile.list();
        if (!(new File(targetPath)).exists()) {
            boolean mkdir = (new File(targetPath)).mkdir();
            if (!mkdir) System.out.println("创建文件权限不足");
        }
        try {
            assert fileList != null;
            for (String s : fileList) {
                String AllSourcePath = sourcePath + FileUtil.separator + s;
                String AllTargetPath = targetPath + FileUtil.separator + s;

                Path fileScan = FileSystems.getDefault().getPath(AllSourcePath);
                if ((new File(AllTargetPath)).exists()){
                    Files.delete(fileScan);
                    continue;
                }
                Path fileTarget = FileSystems.getDefault().getPath(AllTargetPath);
                Files.move(fileScan, fileTarget);
            }
            Path path = FileSystems.getDefault().getPath(sourcePath + FileUtil.separator);
            Files.delete(path);
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}
